# encoding: UTF-8

'''
Wind Python API的gateway接入
'''

from copy import copy

try:
	from WindPy import w
except ImportError:
	print u'请先安装WindPy接口'

from vtGateway import *

# 交易所类型映射
exchangeMap = {}
exchangeMap[EXCHANGE_SSE] = 'SH'
exchangeMap[EXCHANGE_SZSE] = 'SZ'
exchangeMap[EXCHANGE_CFFEX] = 'CFE'
exchangeMap[EXCHANGE_SHFE] = 'SHF'
exchangeMap[EXCHANGE_DCE] = 'DCE'
exchangeMap[EXCHANGE_CZCE] = 'CZC'
exchangeMap[EXCHANGE_UNKNOWN] = ''
exchangeMapReverse = {v:k for k,v in exchangeMap.items()}


########################################################################
class WindGateway(VtGateway):
	"""Wind接口"""
	# 订阅wsq时传入的字段列表
	wsqParamMap = {}
	wsqParamMap['rt_last'] = 'lastPrice'
	wsqParamMap['rt_last_vol'] = 'volume'
	wsqParamMap['rt_oi'] = 'openInterest'

	wsqParamMap['rt_open'] = 'openPrice'
	wsqParamMap['rt_high'] = 'highPrice'
	wsqParamMap['rt_low'] = 'lowPrice'
	wsqParamMap['rt_pre_close'] = 'preClosePrice'
					
	wsqParamMap['rt_high_limit'] = 'upperLimit'
	wsqParamMap['rt_low_limit'] = 'lowerLimit'

	wsqParamMap['rt_bid1'] = 'bidPrice1'
	wsqParamMap['rt_bid2'] = 'bidPrice2'
	wsqParamMap['rt_bid3'] = 'bidPrice3'
	wsqParamMap['rt_bid4'] = 'bidPrice4'
	wsqParamMap['rt_bid5'] = 'bidPrice5'
					
	wsqParamMap['rt_ask1'] = 'askPrice1'
	wsqParamMap['rt_ask2'] = 'askPrice2'
	wsqParamMap['rt_ask3'] = 'askPrice3'
	wsqParamMap['rt_ask4'] = 'askPrice4'
	wsqParamMap['rt_ask5'] = 'askPrice5'
					
	wsqParamMap['rt_bsize1'] = 'bidVolume1'
	wsqParamMap['rt_bsize2'] = 'bidVolume2'
	wsqParamMap['rt_bsize3'] = 'bidVolume3'
	wsqParamMap['rt_bsize4'] = 'bidVolume4'
	wsqParamMap['rt_bsize5'] = 'bidVolume5'
					
	wsqParamMap['rt_asize1'] = 'askVolume1'
	wsqParamMap['rt_asize2'] = 'askVolume2'
	wsqParamMap['rt_asize3'] = 'askVolume3'
	wsqParamMap['rt_asize4'] = 'askVolume4'
	wsqParamMap['rt_asize5'] = 'askVolume5'
	
	wsqParam = ','.join(wsqParamMap.keys())

	#----------------------------------------------------------------------
	def __init__(self, eventEngine, gatewayName='Wind'):
		"""Constructor"""
		super(WindGateway, self).__init__(eventEngine, gatewayName)
		
		self.w = w				  # Wind API对象
		self.connected = False	  # 连接状态
		
		# Wind的wsq更新采用的是增量更新模式，每次推送只会更新发生变化的字段
		# 而vt中的tick是完整更新，因此需要本地维护一个所有字段的快照
		self.tickDict = {}
		
		self.registerEvent()
		
	#----------------------------------------------------------------------
	def connect(self):
		"""连接"""
		# 由于w.start方法会阻塞较长时间
		# 因此设计为异步模式，交给事件处理线程去处理
		# 另外w.start和WingIDE的debug模块有冲突，会导致异常退出
		event = Event(type_=EVENT_WIND_CONNECTREQ)
		self.eventEngine.put(event)
		
	#----------------------------------------------------------------------
	def subscribe(self, subscribeReq):
		"""订阅行情"""
		windSymbol = '.'.join([subscribeReq.symbol, exchangeMap[subscribeReq.exchange]])
		data = self.w.wsq(windSymbol, self.wsqParam, func=self.wsqCallBack)
	
	#----------------------------------------------------------------------
	def sendOrder(self, orderReq):
		"""发单"""
		log = VtLogData()
		log.gatewayName = self.gatewayName
		log.logContent = u'Wind接口未实现发单功能'
		self.onLog(log)
	
	#----------------------------------------------------------------------
	def cancelOrder(self, cancelOrderReq):
		"""撤单"""
		log = VtLogData()
		log.gatewayName = self.gatewayName
		log.logContent = u'Wind接口未实现撤单功能'
		self.onLog(log)
	
	#----------------------------------------------------------------------
	def getAccount(self):
		"""查询账户资金"""
		log = VtLogData()
		log.gatewayName = self.gatewayName
		log.logContent = u'Wind接口未实现查询账户功能'
		self.onLog(log)
	
	#----------------------------------------------------------------------
	def getPosition(self):
		"""查询持仓"""
		log = VtLogData()
		log.gatewayName = self.gatewayName
		log.logContent = u'Wind接口未实现查询持仓功能'
		self.onLog(log)
	
	#----------------------------------------------------------------------
	def close(self):
		self.w.stop()
	 
	#----------------------------------------------------------------------
	def registerEvent(self):
		"""注册事件监听"""
		self.eventEngine.register(EVENT_WIND_CONNECTREQ, self.wConnect)
		
	#----------------------------------------------------------------------
	def wsqCallBack(self, data):
		"""收到wsq推送"""
		windSymbol = data.Codes[0]
		if windSymbol in self.tickDict:
			tick = self.tickDict[windSymbol]
		else:
			tick = VtTickData()
			tick.gatewayName = self.gatewayName
			symbolSplit = windSymbol.split('.')
			tick.symbol = symbolSplit[0]
			tick.exchange = exchangeMapReverse[symbolSplit[1]]
			tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
			self.tickDict[windSymbol] = tick

		dt = data.Times[0]
		tick.time = dt.strftime('%H:%M:%S')
		tick.date = dt.strftime('%Y%m%d')
		
		# 采用遍历的形式读取数值
		fields = data.Fields
		values = data.Data
		d = tick.__dict__
		for n, field in enumerate(fields):
			field = field.lower()
			key = self.wsqParamMap[field]
			value = values[n][0]
			d[key] = value
		
		newtick = copy(tick)
		self.onTick(newtick)
	
	#----------------------------------------------------------------------
	def wConnect(self, event):
		"""利用事件处理线程去异步连接Wind接口"""
		result = self.w.start()
		
		log = VtLogData()
		log.gatewayName = self.gatewayName
		
		if not result.ErrorCode:
			log.logContent = u'Wind接口连接成功'
		else:
			log.logContent = u'Wind接口连接失败，错误代码%d' %result.ErrorCode
		self.onLog(log)